#include "ASET.h"

ASET_T* ASET_t;



//************************************
// Method:    	CALCU_SAMA					//< SAMA运算函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	bool						//< 成功：true；失败：false
// Parameter: 	Model_Base_t * arg			//< 模块参数结构体指针
// Parameter: 	float dt					//< 运算周期
// Parameter: 	bool * DI					//< 数字量输入值数组指针
// Parameter: 	bool * DO					//< 数字量输出值数组指针
// Parameter: 	bool * AI					//< 模拟量输入值数组指针
// Parameter: 	bool * AO					//< 模拟量输出值数组指针
//************************************
bool CALCU_SAMA(ASET)(Model_Base_t* arg, float dt, bool* DI, bool* DO, float* AI, float* AO)
{
	/****************变量定义区开始**************/
	/*<<<<<定义输入变量>>>>>*/
	float PV;					//< 过程值
	float SP;					//< 设定值

	bool PV_TR;					//< 跟踪PV信号，true为跟踪，false为不跟踪
	bool SP_TR;					//< 跟踪SP信号，true为跟踪，false为不跟踪
	bool Mode_Choose;			//< 工作模式选择，true——跟踪模式：输出跟踪PV，false——设定模式：输出由初始值及按钮操作获得
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<定义输出变量>>>>>*/
	float Output_Value;			//< 输出值
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<定义中间变量>>>>>*/
	bool* Button_Pressed;		//< 按钮是否被按下，按下为true，未按下为false
	float* Change_Rate;			//< 按钮一直被按下时，输出值改变的速率
	float* Button_Pressed_Time;	//< 按钮被一直按下的时间累计值
	float* Out_Value;			//< 模块输出值
	/*<<<<<<<<<<<<<<<<<<<<<<*/
	/****************变量定义区结束**************/

	NAME(ASET)* Obj = (NAME(ASET)*)arg;

	/****************变量赋值**************/
	/*<<<<<输入变量赋值>>>>>*/
	PV = AI[0];
	SP = AI[1];

	PV_TR = DI[0];
	SP_TR = DI[1];
	Mode_Choose = DI[2];
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<中间变量赋值（由于中间变量属于静态变量，其数值要随运算而更新，
	因此此处建议将中间变量的地址赋值给相应变量，省去了运算完成后再次赋值
	给中间变量的过程）>>>>>*/
	Button_Pressed = &(Obj->Sta.Button_Pressed);
	Change_Rate = &(Obj->Sta.Change_Rate);
	Button_Pressed_Time = &(Obj->Sta.Button_Pressed_Time);
	Out_Value = &(Obj->Sta.Out_Value);
	/*<<<<<<<<<<<<<<<<<<<<<<*/
	/**************变量赋值结束************/

	/********************************************/
	/**************算法功能实现开始**************/
	/********************************************/
	if (Mode_Choose == true)			//< 工作在跟踪模式
	{
		Out_Value[0] = PV;
	}
	else								//< 工作在设定模式
	{
		if (PV_TR == true)				//< 跟踪PV
		{
			Out_Value[0] = PV;
		}
		else if (SP_TR == true)			//< 跟踪SP
		{
			Out_Value[0] = SP;
		}
		//else							//< 不跟踪PV或SP
		//{
		//	if (Button_Pressed[0] == true)
		//	{
		//		Button_Pressed_Time[0] += dt;	//< 时间累加
		//		if (Button_Pressed_Time[0] >= 2)
		//		{
		//			Button_Pressed_Time[0] = 2;
		//			Out_Value[0] += Change_Rate[0] * dt;
		//		}

		//	}
		//}
	}

	Output_Value = Out_Value[0];		//< 给输出值赋值
	/********************************************/
	/**************算法功能实现结束**************/
	/********************************************/

	/****************运算结果输出**************/
	AO[0] = Output_Value;
	/**************运算结果输出完毕************/
	return true;
}



//************************************
// Method:    	BCPARA						//< 广播SAMA参数变量函数（无参数需要广播的模块直接将BCPara函数设置为NULL即可）
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg			//< 模块参数结构体指针
// Parameter: 	void ** Data				//< 广播SAMA参数的数据包的指针
//************************************
int BC_PARA(ASET)(Model_Base_t* arg, void** Data)
{
	NAME(ASET)* Obj = (NAME(ASET)*)arg;
	BC_PARA_PUBLIC(Obj);
	return 0;
}



//************************************
// Method:    	BAK_STA						//< 备份SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg			//< 指定模块类型链表的指针
// Parameter: 	void ** Data				//< 存放数据包当前指针位置的地址
//************************************
int BAK_STA(ASET)(Model_Base_t* arg, void** Data)
{
	NAME(ASET)* Obj = (NAME(ASET)*)arg;
	BAK_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	ANA_STA							//< 解析备份的SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int								//< 成功：返回解析字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	void ** Data					//< 存放数据包当前指针位置的地址
//************************************
int ANA_STA(ASET)(Model_Base_t* arg, void** Data)
{
	NAME(ASET)* Obj = (NAME(ASET)*)arg;
	ANA_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	CHANGE_PAR					//< 在线修改模块参数函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							//< 读取字节长度计数值
// Parameter: 	Model_Base_t* arg			//< 指定模块类型链表的指针
// Parameter: 	void** Data					//< 存放数据包当前指针位置的地址
//************************************
int CHANGE_PAR(ASET)(Model_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD(((NAME(ASET)*)arg)->Par, Data[0]);
	return _iLen;
}



//************************************
// Method:    	INIT_STAPAR					//< 初始化模块运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Parameter: 	Model_Base_t* arg			//< 模块参数结构体指针
//************************************
void INIT_STAPAR(ASET)(Model_Base_t* arg)
{
	NAME(ASET)* name = (NAME(ASET)*)arg;
	/****************初始化中间变量结构体**************/
	memset(&(name->Sta), 0, sizeof(name->Sta));
	/**************初始化中间变量结构体结束************/

	/****************对中间变量结构体的相关参数进行赋值**************/
	name->Sta.Out_Value = name->Par.Init_Out_Value;
	/**************对中间变量结构体的相关参数进行赋值结束************/
}



//************************************
// Method:    	CMD_DEAL					//< 与模块相关的命令字处理函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	void					
// Parameter: 	Model_Base_t* arg			//< 指定模块类型链表的指针
// Parameter: 	void* Data					//< 信息头指针
// Parameter: 	char* CMD					//< 命令字
//************************************
void CMD_DEAL(ASET)(Model_Base_t* arg, void* Data, const char* CMD)
{
#define	MEMREAD1(var)	MEMREAD(var, Data)

	int _iLen = 0;
	float tmp_float;

	NAME(ASET)* name = (NAME(ASET)*)arg;

	if (!strcmp(CMD, "FAO"))			//< 直接输出命令
	{
		MEMREAD1(name->Sta.Out_Value);
	}
	else if (!strcmp(CMD, "MAO"))		//< 模拟量“增”、“减”命令
	{
		MEMREAD1(tmp_float);											//< duan0902 输出值
		MEMREAD1(name->Sta.Change_Rate);								//< duan0831 上位下发的该参数为“0”
		/*name->Sta.Button_Pressed = true;
		name->Sta.Button_Pressed_Time = 0;*/

		name->Sta.Out_Value += tmp_float;
	}
	else if (!strcmp(CMD, "HAO"))		//< 按钮弹起后发送的命令字
	{
		/*name->Sta.Button_Pressed = false;
		MEMREAD1(tmp_float);
		if (name->Sta.Button_Pressed_Time < 2)
			name->Sta.Out_Value += tmp_float;

		name->Sta.Button_Pressed_Time = 0;*/
	}

#undef MEMREAD1
}
